/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * GridDevPanel.java
 *
 * Created on 24/12/2009, 15:13:08
 */

package com.power.visual;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import net.java.dev.transparentlayout.TransparentLayout;

/**
 *
 * @author f6036477
 */
public class GridDevPanel extends javax.swing.JPanel 
    implements MouseListener, MouseMotionListener {

  private int celSize;

  public static final int DEFAULT_CEL_SIZE = 5;

  private Color gridColor = Color.LIGHT_GRAY;

  private Color selectionColor = new Color(120, 171, 223);

  private Color origColor;

  private Point p1;

  private Point p2;

  private Point p;

  private Rectangle curPosition;

  private Rectangle curSelection;

  private BufferedImage buffer;

  private boolean lockSelection;

  private boolean isSelected;


  public GridDevPanel()
  {
    this(DEFAULT_CEL_SIZE);
  }

  /** Creates new form GridDevPanel */
  public GridDevPanel(int celSize)
  {
    //initComponents();
    this.setLayout(null);
    //this.setLayout(null);

    this.celSize = celSize;
    lockSelection = false;
    isSelected = false;
    curSelection = new Rectangle();
    curPosition = new Rectangle();

    p = new Point();
    p1 = new Point();
    p2 = new Point();

    origColor = this.getBackground();
    this.addMouseListener(this);
    this.addMouseMotionListener(this);

    System.out.println( "Button1 = "+ MouseEvent.BUTTON1 );
  }

  protected Point translatePosition(Point point)
  {
    Point tp = new Point(0, 0);
    tp.x = point.x / celSize;
    tp.y = point.y / celSize;
    tp.x *= celSize;
    tp.y *= celSize;
    return tp;
  }

  @Override
  protected void paintComponent(Graphics g)
  {
    super.paintComponent(g);
    this.updateSize();
    this.updateBuffer();
    g.drawImage(buffer, 0, 0, null);
  }

  protected void updateBuffer()
  {
    if(  buffer == null ||
        (buffer.getWidth() < this.getWidth() ||
         buffer.getHeight() < this.getHeight()) ) {
      buffer = null;
      buffer = new BufferedImage(this.getWidth(),
          this.getHeight(), BufferedImage.TRANSLUCENT);
      buffer.setAccelerationPriority(0.99f);
    }

    Graphics2D g = (Graphics2D) buffer.getGraphics();

    g.setColor(origColor);

    g.fillRect(0, 0, buffer.getWidth(), buffer.getHeight());

    g.setColor(gridColor);

    for(int i = celSize; i < buffer.getWidth(); i += celSize)
    {
      g.drawLine(i, 0, i, buffer.getHeight());
    }//for

    for(int j = celSize; j < buffer.getHeight(); j += celSize)
    {
      g.drawLine(0, j, buffer.getWidth(), j);
    }//for

    g.setColor(selectionColor);

    g.setComposite(AlphaComposite.getInstance(
        AlphaComposite.SRC_OVER, .7f));

    if(isSelected || lockSelection)
      g.fillRect(curSelection.x +1, curSelection.y +1,
          curSelection.width -1, curSelection.height -1);
    
    if(isSelected || !lockSelection)
      g.fillRect(curPosition.x +1, curPosition.y +1,
          curPosition.width -1, curPosition.height -1);
  }

  protected void updateSize()
  {
    this.setSize(this.getWidth() / this.celSize * this.celSize + this.celSize,
            this.getHeight() / this.celSize * this.celSize + this.celSize);
  }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 463, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 352, Short.MAX_VALUE)
    );
  }// </editor-fold>//GEN-END:initComponents


  // Variables declaration - do not modify//GEN-BEGIN:variables
  // End of variables declaration//GEN-END:variables

  @Override
  public void mouseClicked(MouseEvent e)
  {
    System.out.println( e.getButton() );
    if(e.getButton() == MouseEvent.BUTTON1)
      this.unselect();
    else
      System.out.println( this.replaceSelection(new JButton("Button")) );
  }

  @Override
  public void mousePressed(MouseEvent e)
  {
    p1 = this.translatePosition(e.getPoint());

    lockSelection = true;
    isSelected = false;
    this.repaint();
  }

  @Override
  public void mouseReleased(MouseEvent e)
  {
    lockSelection = false;
    isSelected = true;
  }

  @Override
  public void mouseEntered(MouseEvent e)
  {
  }

  @Override
  public void mouseExited(MouseEvent e)
  {
  }

  @Override
  public void mouseDragged(MouseEvent e)
  {
    p2 = this.translatePosition(e.getPoint());

    int width, height, x, y;
    width = p2.x - p1.x + celSize;
    height = p2.y - p1.y + celSize;

    x = p1.x;
    y = p1.y;

    if(p2.x < p1.x) {
      width = p1.x - p2.x + celSize;
      x = p2.x;
    }

    if(p2.y < p1.y) {
      height = p1.y - p2.y + celSize;
      y = p2.y;
    }

    curSelection.x = x;
    curSelection.y = y;
    curSelection.width = width;
    curSelection.height = height;

    System.out.println( curSelection );

    this.repaint();
  }

  @Override
  public void mouseMoved(MouseEvent e)
  {
    p = this.translatePosition(e.getPoint());
    curPosition.x = p.x;
    curPosition.y = p.y;
    curPosition.width = celSize;
    curPosition.height = celSize;
    this.repaint();
  }

  public void unselect()
  {
    curSelection.x = 0;
    curSelection.y = 0;
    curSelection.width = 0;
    curSelection.height = 0;
  }

  public boolean replaceSelection(Component c)
  {
    c.setBounds(new Rectangle(curSelection.x, curSelection.y,
        curSelection.width, curSelection.height));
    this.add(c);
    this.unselect();
    return true;
  }


  public static void main(String[] args)
  {
    JFrame f = new JFrame("GridDevPanel");
    f.setLayout(new TransparentLayout());
    f.setBounds(300, 300, 425, 450);

    GridDevPanel gd = new GridDevPanel();

    f.add(gd, new Rectangle(0, 0, 400, 400));
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
  }

}
